package com.yunxin.admin.system.infra.persistence.repository;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunxin.admin.system.domain.model.user.UserRoleRepository;
import com.yunxin.admin.system.infra.common.constant.SystemConstants;
import com.yunxin.admin.system.infra.common.enums.AdminResultCode;
import com.yunxin.admin.system.infra.persistence.entity.SysUserRoleDO;
import com.yunxin.admin.system.infra.persistence.mapper.SysUserRoleMapper;
import com.yunxin.common.exception.BusinessException;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author zero°
 * @since 2023-07-11
 */
@Repository
public class UserRoleRepositoryImpl extends ServiceImpl<SysUserRoleMapper, SysUserRoleDO> implements UserRoleRepository, IService<SysUserRoleDO> {

    @Override
    public boolean saveUserRoles(Long userId, List<Long> roleIds) {
        if (userId == null || CollUtil.isEmpty(roleIds)) {
            return false;
        }
        // 用户原角色ID集合
        List<Long> userRoleIds = this.list(new LambdaQueryWrapper<SysUserRoleDO>()
                        .eq(SysUserRoleDO::getUserId, userId))
                .stream()
                .map(SysUserRoleDO::getRoleId)
                .toList();
        // 用户已存在商户且更新的商户id与历史存在的商户id不一致，则不允许更新(因为系统用户变更商户时,未变更商户账号中的商户id)
        if(CollUtil.isNotEmpty(userRoleIds) && userRoleIds.contains(SystemConstants.DEFAULT_MERCHANT_USER_ROLE_ID)) {
            throw new BusinessException(AdminResultCode.USER_MERCHANT_USER_ROLE_CHANGE_ERROR);
        }
        // 新增用户角色
        List<Long> saveRoleIds;
        if (CollUtil.isEmpty(userRoleIds)) {
            saveRoleIds = roleIds;
        } else {
            saveRoleIds = roleIds.stream()
                    .filter(roleId -> !userRoleIds.contains(roleId)).toList();
        }

        List<SysUserRoleDO> saveUserRoles = saveRoleIds
                .stream()
                .map(roleId -> new SysUserRoleDO(userId, roleId)).toList();
        this.saveBatch(saveUserRoles);
        // 删除用户角色
        if (CollUtil.isNotEmpty(userRoleIds)) {
            List<Long> removeRoleIds = userRoleIds.stream()
                    .filter(roleId -> !roleIds.contains(roleId)).toList();

            if (CollUtil.isNotEmpty(removeRoleIds)) {
                this.remove(new LambdaQueryWrapper<SysUserRoleDO>()
                        .eq(SysUserRoleDO::getUserId, userId)
                        .in(SysUserRoleDO::getRoleId, removeRoleIds)
                );
            }
        }
        return true;
    }

    @Override
    public long count(Long roleId) {
        return this.count(new LambdaQueryWrapper<SysUserRoleDO>().eq(SysUserRoleDO::getRoleId, roleId));
    }

}
